
#pragma once

#include "..\\ExternalTools\\ExternalTools.h"

#include "..\\Loirey\\loirey_GLOBAL.h"
#include "..\\Loirey\\loirey_MyMath.h"
#include "..\\Loirey\\loirey_BasicStructure.h"

using namespace loirey;

class CRectHistogram
{
public:
	class CParameters
	{
	public:
		static const int L2_NORM = 0;
		static const int L2_HYS = 1;
	public:
		int BinAmount;
		double e;

		double WeightScale;

		int normalizer;
		double hysth;

		int wWinCel;
		int hWinCel;

		int wBlkCel;
		int hBlkCel;

		int wWinBlk;
		int hWinBlk;

		int aWinCel;
		int aBlkCel;
		int aWinBlk;

		int lenBlkDescriptor;
		int lenWinDescriptor;

	public:
		CParameters();
		void Clear();
		void myInit(istream& inStream);
		void myInit(
			int BinAmount,
			int wWinCel, int hWinCel,
			int wBlkCel, int hBlkCel,
			double WeightScale,
			string strNormalizer, double hysTheshold,
			double e
			);
	};
	class CWindowDescriptor
	{
	protected:
		bool _fIsImagePreprocessed;
	public:
		CRectHistogram* pSource;
		CRectBox<int> Box;

		CHistogramConfig HistogramParameter;
		CParameters RectHist_Parameters;

		int W,H,WH;

		CSimpleTypeArray<double> matW_A;
		CSimpleTypeArray<double> matW_B;
		CSimpleTypeArray<int> matV_A;
		CSimpleTypeArray<int> matV_B;
		
		CSimpleTypeArray<double> IntegralHistogramMap;

		int _CelQuery;
		int _CelCalc;
		map<int, int> CellCache;
		CSimpleTypeArray<double> CellData;

		CSimpleTypeArray<int> BlkCache;
		CSimpleTypeArray<double> BlkData;
		int _BlkQuery;
		int _BlkCalc;

	protected:
		void _PreprocessImage();

		void _Real_PreprocessImage_A();
		void _CalcBlockDescriptor_A(double* DstDescriptor, double xBase, double yBase, double wCel, double hCel);

		void _Real_PreprocessImage_B();
		void _CalcBlockDescriptor_B(double* DstDescriptor, double xBase, double yBase, double wCel, double hCel);
		void _CalcCellHistogram_B(double* DstHistogram, int xL, int yL, int xH, int yH);

		//void _CalcCellHistogram_GW(int xCel, int yCel, double gx, double gy, double* DstCellData);
	public:
		CWindowDescriptor();
		void myInit();
		void ClearCalculationHistory();
		void SetParameters(const CParameters& RectHist_Parameters, double ValueBoundA, double ValueBoundB, bool fAreBinsWrapped);
		void SetImage(CRectHistogram* pSource);
		void SetWindow(const CRectBox<int>& Box);
		void WorkOnBlock(
			int xBlk, int yBlk,
			double* dstBlockDescriptor
			);
	};

public:
	int W, H, WH;
	CSimpleTypeArray<double> matWeight;
	CSimpleTypeArray<double> matValue;

	CWindowDescriptor WindowDescriptor;

public:
	CRectHistogram();
	void Clear();
	void SetData(int W, int H, const double* matWeight, const double* matValue);
	void SetData(int W, int H, const double* matValue);
	void WorkOnBlock(
		const CRectBox<int>& Box,
		int xBlk, int yBlk,
		double* dstBlockDescriptor
		);
};

